package com.tianji.aigc.service.impl;

import cn.hutool.core.stream.StreamUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.aigc.config.SessionProperties;
import com.tianji.aigc.entity.ChatSession;
import com.tianji.aigc.enums.MessageTypeEnum;
import com.tianji.aigc.mapper.ChatSessionMapper;
import com.tianji.aigc.memory.MyAssistantMessage;
import com.tianji.aigc.memory.RedisChatMemory;
import com.tianji.aigc.service.ChatSessionService;
import com.tianji.aigc.vo.HistorySessionVO;
import com.tianji.aigc.vo.MessageVO;
import com.tianji.aigc.vo.SessionVO;
import com.tianji.common.utils.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;


@Service
@RequiredArgsConstructor
public class ChatSessionServiceImpl extends ServiceImpl<ChatSessionMapper, ChatSession> implements ChatSessionService {

    private final SessionProperties sessionProperties;

    private final ChatServiceImpl chatService;

    private final RedisChatMemory redisChatMemory;

    /**
     * 创建会话
     *
     * @param num 热门话题数量
     * @return 会话信息
     */
    @Override
    public SessionVO createSession(Integer num) {
        String sessionId = IdUtil.fastSimpleUUID();
        ChatSession chatSession = ChatSession.builder()
                .sessionId(sessionId)
                .userId(UserContext.getUser())
                .title(sessionProperties.getTitle())
                .build();

        SessionVO sessionVO = SessionVO.builder()
                .sessionId(sessionId)
                .title(sessionProperties.getTitle())
                .describe(sessionProperties.getDescribe())
                .examples(RandomUtil.randomEleList(sessionProperties.getExamples(), num))
                .build();

        save(chatSession);

        return sessionVO;
    }

    /**
     * 热门会话
     * @param num 热门话题数量
     * @return 热门问题
     */
    @Override
    public List<SessionVO.Example> hotChat(Integer num) {
         return RandomUtil.randomEleList(sessionProperties.getExamples(), num);
    }

    /**
     * 查询会话内容
     *
     * @param sessionId 会话id
     * @return 会话内容
     */
    @Override
    public List<MessageVO> queryBySessionId(String sessionId) {
        // 根据会话ID获取对话ID
        String conversationId = chatService.getConversationId(sessionId);
        // 从Redis中获取历史消息
        List<Message> messageList = redisChatMemory.get(conversationId,100);
        // 过滤并转换消息列表
        return StreamUtil.of(messageList)
                // 过滤掉非用户消息和助手消息
                .filter(message -> message.getMessageType() == MessageType.ASSISTANT || message.getMessageType() == MessageType.USER)
                // 转换为MessageVO对象
                .map(message -> {
                    if (message instanceof MyAssistantMessage) {
                        return MessageVO.builder()
                                .content(message.getText())
                                .type(MessageTypeEnum.valueOf(message.getMessageType().name()))
                                .params(((MyAssistantMessage) message).getParams())
                                .build();
                    }
                    return MessageVO.builder()
                            .content(message.getText())
                            .type(MessageTypeEnum.valueOf(message.getMessageType().name()))
                            .build();
                })
                .toList();
    }

    @Override
    public Map<String, List<HistorySessionVO>> queryHistory() {
        // 查询数据库中的会话记录，需要包含 sessionId、title 和 updateTime 字段
        List<ChatSession> chatSessions = this.list();

        // 转换为 HistorySessionVO 列表
        List<HistorySessionVO> historySessions = chatSessions.stream()
                .map(session -> HistorySessionVO.builder()
                        .sessionId(session.getSessionId())
                        .title(session.getTitle())
                        .updateTime(session.getUpdateTime())
                        .build())
                .toList();

        // 初始化各个时间段的列表
        Map<String, List<HistorySessionVO>> result = new LinkedHashMap<>();
        result.put("当天", new ArrayList<>());
        result.put("最近30天", new ArrayList<>());
        result.put("最近1年", new ArrayList<>());
        result.put("1年以上", new ArrayList<>());

        LocalDateTime now = LocalDateTime.now();
        LocalDate today = LocalDate.now();

        for (HistorySessionVO session : historySessions) {
            LocalDateTime updateTime = session.getUpdateTime();
            LocalDate updateDate = updateTime.toLocalDate();

            if (updateDate.equals(today)) {
                result.get("当天").add(session);
            } else if (updateTime.isAfter(now.minusDays(30))) {
                result.get("最近30天").add(session);
            } else if (updateTime.isAfter(now.minusYears(1))) {
                result.get("最近1年").add(session);
            } else {
                result.get("1年以上").add(session);
            }
        }

        return result;
    }

    @Override
    public void updateHistory(String sessionId, String title) {
        // 构造更新条件
        LambdaUpdateWrapper<ChatSession> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ChatSession::getSessionId, sessionId)
                .set(ChatSession::getTitle, title);

        // 执行更新操作
        this.update(updateWrapper);
    }

    @Override
    public void deleteHistory(String sessionId) {
        // 根据会话ID删除记录
        LambdaQueryWrapper<ChatSession> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatSession::getSessionId, sessionId);
        this.remove(queryWrapper);

        // 删除Redis中的会话信息
        String conversationId = chatService.getConversationId(sessionId);
        redisChatMemory.clear(conversationId);
    }

}
